home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
alpha
/
dipc
/
dipc-0.000
/
dipc-0
/
dipc-0.15
/
dipcd
/
back_end.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-16
|
9KB
|
365 lines
/*
* back_end.c
*
* part of dipcd source code
*
* Copyright (C) Kamran Karimi
*/
#include "dipcd.h"
#include "funcs.h"
/* back_end forks the necessary processes and the sleep in the kernel,
wait for work to become available. It then forks an employer to handle
it */
struct sockaddr_in MY_LBACK, REFEREE_LBACK;
struct sockaddr_in MY_ADDRESS, REFEREE_ADDRESS;
int verbose;
int global_timeout;
int employer_referee_timeout;
int employer_shm_timeout;
int employer_worker_timeout;
int referee_timeout;
int shm_ak_timeout;
double shm_hold_timeout;
/* used in parsing dipcd configuration file */
static void strip_space(char *buff)
{
char buff2[160];
int count, count2 = 0;
for(count = 0; count < strlen(buff); count++)
{
if(buff[count] == ' ' || buff[count] == '\t')
continue;
buff2[count2] = buff[count];
count2++;
}
buff2[count2] = 0;
strcpy(buff, buff2);
}
/* read my address and the referee address, plus time-out values and put them
in globaly known variables */
static BOOLEAN init_dipc(void)
{
long count;
char *pos, buff[160];
FILE *file;
struct in_addr addr;
/* default values */
employer_referee_timeout = EMPLOYER_REFEREE_TIMEOUT;
employer_shm_timeout = EMPLOYER_SHM_TIMEOUT;
employer_worker_timeout = EMPLOYER_WORKER_TIMEOUT;
shm_ak_timeout = SHM_AK_TIMEOUT;
referee_timeout = REFEREE_TIMEOUT;
shm_hold_timeout = SHM_HOLD_TIMEOUT;
/* the address of this computer and the referee's computer SHOULD be
given */
REFEREE_ADDRESS.sin_addr.s_addr = -1;
MY_ADDRESS.sin_addr.s_addr = -1;
addr.s_addr = -1;
file = fopen(CONFIG_FILE,"r");
if(file == NULL)
{
sprintf(mstr,"ERROR: Can't Open Config File %s BECAUSE %s",
CONFIG_FILE, strerror(errno));
mess(mstr, INFO);
return FAIL;
}
while(fgets(buff,80,file))
{
pos = strchr(buff, '#'); /* no comments */
if(pos) *pos = 0;
strip_space(buff);
pos = strchr(buff, '=');
if(pos == NULL) continue;
*pos = 0;
if(!strcasecmp(buff,"this_machine"))
{
pos++;
count = 0;
while((count < strlen(pos)) && !isdigit(pos[count])) count++;
addr.s_addr = inet_addr(&pos[count]);
if((addr.s_addr != -1) && strcasecmp((char *)inet_ntoa(addr),"0.0.0.0"))
{
bzero((char *)&MY_ADDRESS, sizeof(MY_ADDRESS));
MY_ADDRESS.sin_family = AF_INET;
MY_ADDRESS.sin_addr.s_addr = addr.s_addr;
MY_ADDRESS.sin_port = htons(DIPC_TCP_PORT);
}
}
else if(!strcasecmp(buff,"referee"))
{
pos++;
count = 0;
while((count < strlen(pos)) && !isdigit(pos[count])) count++;
addr.s_addr = inet_addr(&pos[count]);
if((addr.s_addr != -1) && strcasecmp((char *)inet_ntoa(addr),"0.0.0.0"))
{
bzero((char *)&REFEREE_ADDRESS, sizeof(REFEREE_ADDRESS));
REFEREE_ADDRESS.sin_family = AF_INET;
REFEREE_ADDRESS.sin_addr.s_addr = addr.s_addr;
REFEREE_ADDRESS.sin_port = htons(DIPC_REFEREE_PORT);
}
}
else if(!strcasecmp(buff,"employer_referee_timeout"))
{
pos++;
employer_referee_timeout = atoi(pos);
}
else if(!strcasecmp(buff,"employer_shm_timeout"))
{
pos++;
employer_shm_timeout = atoi(pos);
}
else if(!strcasecmp(buff,"employer_worker_timeout"))
{
pos++;
employer_worker_timeout = atoi(pos);
}
else if(!strcasecmp(buff,"shm_ak_timeout"))
{
pos++;
shm_ak_timeout = atoi(pos);
}
else if(!strcasecmp(buff,"referee_timeout"))
{
pos++;
referee_timeout = atoi(pos);
}
else if(!strcasecmp(buff,"shm_hold_timeout"))
{
pos++;
shm_hold_timeout = atoi(pos);
if(shm_hold_timeout <= 0)
shm_hold_timeout = SHM_HOLD_TIMEOUT;
}
else
{
sprintf(mstr,"ERROR: Unknown option %s",buff);
mess(mstr, INFO);
}
}
if(REFEREE_ADDRESS.sin_addr.s_addr == -1)
{
sprintf(mstr,"ERROR: Can't Find Referee's Address");
mess(mstr, INFO);
return FAIL;
}
if(MY_ADDRESS.sin_addr.s_addr == -1)
{
sprintf(mstr,"ERROR: Can't Find My Own Address");
mess(mstr, INFO);
return FAIL;
}
bzero((char *)&REFEREE_LBACK, sizeof(REFEREE_LBACK));
REFEREE_LBACK.sin_family = AF_INET;
REFEREE_LBACK.sin_addr.s_addr = htonl(INADDR_ANY);
REFEREE_LBACK.sin_port = htons(DIPC_REFEREE_PORT);
bzero((char *)&MY_LBACK, sizeof(MY_LBACK));
MY_LBACK.sin_family = AF_INET;
MY_LBACK.sin_addr.s_addr = htonl(INADDR_ANY);
MY_LBACK.sin_port = htons(DIPC_TCP_PORT);
if(verbose)
{
sprintf(mstr,"employer_worker Timeout is %d secs",employer_worker_timeout);
mess(mstr, INFO);
sprintf(mstr,"employer_shm Timeout is %d secs",employer_shm_timeout);
mess(mstr, INFO);
sprintf(mstr,"employer_referee Timeout is %d secs",employer_referee_timeout);
mess(mstr, INFO);
sprintf(mstr,"shm_ak Timeout is %d secs",shm_ak_timeout);
mess(mstr, INFO);
sprintf(mstr,"referee Timeout is %d secs",referee_timeout);
mess(mstr, INFO);
sprintf(mstr,"shm_hold Timeout is %f secs",shm_hold_timeout);
mess(mstr, INFO);
}
return SUCCESS;
}
static void sig_handler(int signo)
{
if(verbose)
{
sprintf(mstr,"Quiting For Signal No. %d",signo);
mess(mstr, INFO);
}
if(dipc(0,DIPC_REMMNG,NULL) != DIPC_SUCCESS)
{
sprintf(mstr,"ERROR: DIPC_REMMNG failed");
mess(mstr, INFO);
}
/* do last works */
exit(5);
}
void main(int argc, char **argv)
{
int count;
struct dipc_info di;
char data[MAXDATA];
void *pt[2];
pid_t child_pid;
struct sigaction sact;
struct sockaddr_in in_addr;
int in_len, in_sockfd;
int found_work;
if(getuid() != 0)
{
sprintf(mstr,"ERROR: dipcd can not run without root privileges");
mess(mstr, INFO);
exit(20);
}
if(fork() > 0)
exit(0);
chdir("/");
bzero((char *)&in_addr,sizeof(in_addr));
in_addr.sin_family = AF_INET;
in_addr.sin_addr.s_addr = htonl(INADDR_ANY);
in_addr.sin_port = htons(DIPC_TCP_PORT);
in_len = sizeof(in_addr);
in_sockfd = plug(AF_INET, (struct sockaddr *) &in_addr, in_len);
if(in_sockfd < 0)
{
sprintf(mstr,"ERROR: dipcd Is Already Running");
mess(mstr, INFO);
exit(20);
}
close(in_sockfd);
sprintf(mstr,"%s Version %s Started", argv[0], DIPC_VERSION);
mess(mstr, INFO);
verbose = 0;
global_timeout = 1;
for(count = 1; count < argc; count++)
{
if(argv[count][0] == '-')
{
if(argv[count][1] == 'v')
verbose = 1;
else if(argv[count][1] == 't')
global_timeout = 0;
}
}
sact.sa_handler = sig_handler;
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
if(sigaction(SIGINT, &sact, NULL) < 0)
{
sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
mess(mstr, INFO);
}
if(sigaction(SIGTERM, &sact, NULL) < 0)
{
sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
mess(mstr, INFO);
}
if(sigaction(SIGSEGV, &sact, NULL) < 0)
{
sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
mess(mstr,INFO);
}
sact.sa_handler = child_handler;
if(sigaction(SIGCHLD, &sact, NULL) < 0)
{
sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
mess(mstr, INFO);
}
pt[0] = &di;
pt[1] = data;
if(init_dipc() == FAIL) exit(20);
/* register this task as the official dipcd task, responsible for handling
DIPC requests */
if(dipc(MY_ADDRESS.sin_addr.s_addr, DIPC_SETMNG,NULL) < DIPC_SUCCESS)
{
sprintf(mstr,"ERROR: DIPC_SETMNG failed");
mess(mstr, INFO);
exit(20);
}
/* start the front_end task */
if((child_pid = fork()) < 0)
{
sprintf(mstr,"ERROR: Can't fork() BECAUSE %s",strerror(errno));
mess(mstr, INFO);
dipc(0,DIPC_REMMNG,NULL);
exit(20);
}
else if(child_pid == 0)
{
front_end();
exit(20); /* never reaches here */
}
/* see if this is the referee machine */
if(SAME_MACHINE(&MY_ADDRESS,REFEREE_ADDRESS))
{
if((child_pid = fork()) < 0)
{
sprintf(mstr,"ERROR: Can't fork() BECAUSE %s",strerror(errno));
mess(mstr, INFO);
dipc(0,DIPC_REMMNG,NULL);
exit(20);
}
else if(child_pid == 0)
{
referee();
exit(20);
}
}
while(1)
{
if(dipc(0, DIPC_SLEEP, 0) != DIPC_SUCCESS)
{
sprintf(mstr,"ERROR: DIPC_SLEEP failed");
mess(mstr, INFO);
}
found_work = dipc(0,DIPC_GETWORK, pt);
if(found_work < DIPC_SUCCESS)
{
sprintf(mstr,"ERROR: DIPC_GETWORK failed");
mess(mstr, INFO);
}
else if(found_work == DIPC_SUCCESS)
{
if(verbose)
{
sprintf(mstr,"Found work: %s",work_string(di.func));
mess(mstr, INFO);
}
/* only non-local requests will be returned, so create a handler
(employer) for them */
if((child_pid = fork()) < 0)
{
sprintf(mstr,"ERROR: Can't fork() BECAUSE %s",strerror(errno));
mess(mstr, INFO);
di.arg1 = -DIPC_E_FORK;
if(dipc(di.pid, DIPC_RETWORK, (int *)pt) < DIPC_SUCCESS)
{
sprintf(mstr,"ERROR: DIPC_RETWORK failed");
mess(mstr, INFO);
}
}
else if(child_pid == 0)
{
employer(&di, data);
exit(20);
}
}
} /* while(1) */
}